//
//  BleDataTool.swift
//  MMTest
//
//  Created by liujianlong on 2022/9/21.
//

import UIKit
import Foundation
import CoreBluetooth
let BleDataUpdateNotifyName = "BleDataUpdateNotifyName"
public protocol CCBLEData{
    var head:String{get}
    var cmd:String{get}
    var ack:String{get}
    var hex:String{get}
    var data:Data{get}
    var service_uuidString:String{get}
    var write_char_uuidString:String{get}
    var read_char_uuidString:String{get}
    func write(_ peripheral:CBPeripheral?)
    
}

enum BLEData{
    ///清零
    case clear
    ///重启
    case reboot
    ///恢复出厂设置
    case reset
    ///查找设备
    case find
    ///实时数据更新
    case dataupdate
    ///历史数据
    case historyData
    ///电量
    case battery
}

extension BLEData{
    var head:String{
        return "BEFE"
    }
    var cmd : String{
        switch self{
        case .clear:
            return "0500"
        case .reboot:
            return "AA01"
        case .reset:
            return "0701"
        case .find:
            return "0C01"
        default:
            return ""
        }
    }
    
    
    var ack:String{
        switch self{
        case .clear:
            return "05"
        case .reboot:
            return "AA"
        case .reset:
            return "07"
        case .find:
            return "0C"
        case .dataupdate:
            return "01"
        case .historyData:
            return "02"
        default:
            return ""
        }
    }
    
    var data:Data{
        switch self{
        case .clear,
                .reboot,
                .reset,
                .find:
            let str = self.head + "\(self.cmd.count / 2)".fixString(2, "0") + self.cmd
            return str.hexadecimal() ?? Data()
        default:
            return Data()
        }
    }
    
    var service_uuidString:String{
        switch self{
        case .battery:
            return "180F"
        default:
            return "FF00"
        }
    }
    
    var write_char_uuidString:String{
        switch self{
        case .clear,
                .reboot,
                .reset,
                .find:
            return "FF01"
        default:
            return ""
        }
    }
    var read_char_uuidString:String{
        switch self{
        case .clear,
                .reboot,
                .reset,
                .find:
            return "FF02"
        case .dataupdate:
            return "FF03"
        case .historyData:
            return "FF04"
        case .battery:
            return "2A19"
        default:
            return ""
        }
    }
    
    func write(_ peripheral:CBPeripheral?){
        guard let per = peripheral else{return}
        guard let array = per.characteristics[self.service_uuidString] else {return}
        guard let dict = array.filter({$0.keys.first == self.write_char_uuidString}).first else {return}
        guard let char = dict[self.write_char_uuidString] else {return}
        per.writeValue(self.data, for: char, type: .withResponse)
    }
}

class BleDataTool{
    ///数据更新
    class func handleData(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
        let bytes = [UInt8](characteristic.value ?? Data())
        if characteristic.uuid.uuidString == BLEData.battery.read_char_uuidString{
            if bytes.count <= 0{return}
            let current = String(format:"%.2x", bytes[0])
            let b = current.toDecimal()
            ///电量 = b
            NotificationCenter.default.post(name: NSNotification.Name(BleDataUpdateNotifyName), object:peripheral.mac)
            return
        }
        if bytes.count <= 0{return}
        let ack = String(format:"%.2X",bytes[3])
        let data = bytes[0...bytes.count-1].map{String(format:"%.2X ",$0)}.joined()
        var param = [String:Any]()
        switch ack{
        case BLEData.clear.ack:///压力归零
            RLHud.start(LS("压力已经归零"), stopTime: 1, handle: nil)
        case BLEData.reboot.ack:///重启设备
            break
        case BLEData.reset.ack:///恢复出厂设置
            break
        case BLEData.find.ack:///查找设备
            break
        case BLEData.dataupdate.ack:///实时数据返回
            let current_L = String(format:"%.2x%.2x%.2x%.2x", bytes[4],bytes[5],bytes[6],bytes[7])///左手实时重力
            let max_L = String(format:"%.2x%.2x%.2x%.2x", bytes[8],bytes[9],bytes[10],bytes[11])///左手最大
            let avg_L = String(format:"%.2x%.2x%.2x%.2x", bytes[12],bytes[13],bytes[14],bytes[15])///左手平均重力
            let step_L = String(format:"%.2x%.2x%.2x", bytes[16],bytes[17],bytes[18])///左手当天记步
            let battery_L = String(format:"%.2x", bytes[19])///左手电量
            
            var current_R = "0"///右手实时重力
            var max_R = "0"///右手最大
            var avg_R = "0"///右手平均重力
            var step_R = "0"///右手当天记步
            var battery_R = "0"///右手电量
            
            var t_string = "0"///温度
            var p_string = "0"///气压
            var type_string = ""///杖类型
            
            if (peripheral.name ?? "").contains("_R_"){
                current_R = String(format:"%.2x%.2x%.2x%.2x", bytes[20],bytes[21],bytes[22],bytes[23])///右手实时重力
                max_R = String(format:"%.2x%.2x%.2x%.2x", bytes[24],bytes[25],bytes[26],bytes[27])///右手最大
                avg_R = String(format:"%.2x%.2x%.2x%.2x", bytes[28],bytes[29],bytes[30],bytes[31])///右手平均重力
                step_R = String(format:"%.2x%.2x%.2x", bytes[32],bytes[33],bytes[34])///右手当天记步
                battery_R = String(format:"%.2x", bytes[35])///右手电量
                
                t_string = String(format:"%.2x%.2x", bytes[36],bytes[37])///温度
                p_string = String(format:"%.2x%.2x%.2x%.2x", bytes[38],bytes[39],bytes[40],bytes[41])///气压
                type_string = String(format:"%.2x", bytes[42])///杖类型
            }else{
                type_string = String(format:"%.2x", bytes[20])///杖类型
            }
            //            let ss = String(format:"左手实时:%d\n左手最大:%d\n左手平均:%d\n左手计步:%d\n左手电量:%d%%", current_L.toDecimal(),max_L.toDecimal(),avg_L.toDecimal(),step_L.toDecimal(),battery_L.toDecimal())
            //            let ss2 = String(format:"\n右手实时:%d\n右手最大:%d\n右手平均:%d\n右手计步:%d\n右手电量:%d%%", current_R.toDecimal(),max_R.toDecimal(),avg_R.toDecimal(),step_R.toDecimal(),battery_R.toDecimal())
            //            let ss3 = String(format:"\n温度:%d\n气压:%d\n杖类型:%d\n", t_string.toDecimal(),p_string.toDecimal(),type_string.toDecimal())
            print("\(bytes.count)===左手实时：\(current_L),左手最大：\(max_L),左手平均：\(avg_L),左手计步：\(step_L),左手电量：\(battery_L),右手实时：\(current_R),右手最大：\(max_R),右手平均：\(avg_R),右手计步：\(step_R),右手电量：\(battery_R),温度：\(t_string),气压：\(p_string),杖类型：\(type_string)")
            
            //            let text = "\(String(describing: APP.logwindow.input.text!)) \n\n\n"
            //            APP.logwindow.input.text = text + ss + ss2 + ss3
            
            
            APP.singleData.mac = peripheral.mac
            APP.singleData.deviceName = peripheral.name ?? ""
            APP.singleData.l_current = Int32(current_L.toDecimal())
            APP.singleData.l_max = Int32(max_L.toDecimal())
            APP.singleData.l_avg = CGFloat(avg_L.toDecimal())
            APP.singleData.l_step = Int32(step_L.toDecimal())
            APP.singleData.l_batterlevel = Int32(battery_L.toDecimal())
            
            APP.singleData.r_current = Int32(current_R.toDecimal())
            APP.singleData.r_max = Int32(max_R.toDecimal())
            APP.singleData.r_avg = CGFloat(avg_R.toDecimal())
            APP.singleData.r_step = Int32(step_R.toDecimal())
            APP.singleData.r_batterlevel = Int32(battery_R.toDecimal())
            
            APP.singleData.temperature = Int32(t_string.toDecimal())
            APP.singleData.airPressure = Int32(p_string.toDecimal())
            
            APP.singleData.type = Int32(type_string.toDecimal())
            ///发送通知，每次刷新页面
            NotificationCenter.default.post(name: NSNotification.Name(BleDataUpdateNotifyName), object:peripheral.mac)
        case BLEData.historyData.ack:
            break
        default:
            break
        }
    }
}

